//【Day14】LeetCode力扣（解题思路+详细注释）[面试题 01.02.判定是否互为字符重排] [62. 不同路径 ] [205. 同构字符串 ]





/*[面试题 01.02.判定是否互为字符重排]
题目描述：

给定两个字符串 s1 和 s2，请编写一个程序，确定其中一个字符串的字符重新排列后，能否变成另一个字符串。
/
示例 1：
输入: s1 = “abc”, s2 = “bca”
输出: true
/
示例 2：
输入: s1 = “abc”, s2 = “bad”
输出: false
/
说明：
0 <= len(s1) <= 100
0 <= len(s2) <= 100

解题思路：
给定了两个字符串，要求其中一个字符串的字符重新排序后获得另一个字符。

换个角度来思考，只需要两个字符串的字符能一致即可，我们将两个字符串转化为字符数组，一个数组存入集合。

遍历另一个数组的字符，同时与集合中的元素进行比较，比较到不一致的直接返回false，比较到一致的，删除集合中对应元素，继续遍历。

直到遍历完所有字符，集合元素也归零后，说明可以字符重排，返回true
————————————————
版权声明：本文为CSDN博主「.29.」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
原文链接：https://blog.csdn.net/ebb29bbe/article/details/127076853 */



class Solution {
    public boolean CheckPermutation(String s1, String s2) {
        char[] S1 = s1.toCharArray();             //获取s1的字符数组S1
        char[] S2 = s2.toCharArray();             //获取s2的字符数组S2
        List<Character> list = new ArrayList<>(); //创建ArrayList集合

        for(char a : S1){                         //遍历集合S1
            list.add(a);                          //集合元素存入数组
        }

        for(char a : S2){                         //遍历集合S2
            if(!list.contains(a))                 //如果S2存在元素是S1中没有的
            return false;                         //无法字符重排，返回false
            else{                                 //存在对应元素
                list.remove(list.indexOf(a));     //将集合集合中对应的字符删除
            }
        }

        return true;                              //S1、S2所有字符都对应上，可以重排
    }
}





/* [62. 不同路径 ]
题目描述：
一个机器人位于一个 m x n 网格的左上角 （起始点在下图中标记为 “Start” ）。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角（在下图中标记为 “Finish” ）。

问总共有多少条不同的路径？
/

示例 1：

输入：m = 3, n = 7
输出：28
/
示例 2：
输入：m = 3, n = 2
输出：3
解释：
从左上角开始，总共有 3 条路径可以到达右下角。
向右 -> 向下 -> 向下
向下 -> 向下 -> 向右
向下 -> 向右 -> 向下
/
示例 3：
输入：m = 7, n = 3
输出：28
示例 4：
输入：m = 3, n = 3
输出：6

解题思路：
类似于爬楼梯问题，依旧是用动态规划的思路：
我们遍历网格的第一行和第一列，给第一行和第一列赋值上一个路径，每到一个网格，只需要考虑其上位置和左位置的路径数量。
移动到最后终点时，累计的路径数便是总路径数目。
————————————————
版权声明：本文为CSDN博主「.29.」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
原文链接：https://blog.csdn.net/ebb29bbe/article/details/127076853*/

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] step = new int[m][n]; //创建m×n网络
        for(int i = 0;i < m;++i){     //给第一列赋值一个路径
            step[i][0] = 1;
        }
        for(int i = 0;i < n;++i){     //给第一行赋值一个路径
            step[0][i] = 1;
        }  
        for(int i = 1;i < m;++i){     //动态规划地将前面两个位置存在路径累加起来
            for(int j = 1;j < n;++j){
                step[i][j] =step[i-1][j] + step[i][j-1] ;
            }
        }
        return step[m-1][n-1];        //返回抵达终点的所有路径
    }
}










/* [205. 同构字符串 ]
题目描述：

给定两个字符串 s 和 t ，判断它们是否是同构的。
如果 s 中的字符可以按某种映射关系替换得到 t ，那么这两个字符串是同构的。
每个出现的字符都应当映射到另一个字符，同时不改变字符的顺序。不同字符不能映射到同一个字符上，相同字符只能映射到同一个字符上，字符可以映射到自己本身。
示例 1
输入：s = “egg”, t = “add”
输出：true
示例 2：
输入：s = “foo”, t = “bar”
输出：false
示例 3：
输入：s = “paper”, t = “title”
输出：true

解题思路：
使用Map集合来存放键值对，遍历集合中的键值对，当出现于之前存在的键值对起冲突的情况，就代表无法重构了。具体看注释：
————————————————
版权声明：本文为CSDN博主「.29.」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
原文链接：https://blog.csdn.net/ebb29bbe/article/details/127076853*/


class Solution {
    public boolean isIsomorphic(String s, String t) {
        //使用Map集合来存储映射关系
        Map <Character,Character> s2t = new HashMap<Character,Character>();
        Map <Character,Character> t2s = new HashMap<Character,Character>();
        //获取字符串的字符长度
        int length = s.length();
        char x,y;
        for(int i = 0;i < length; ++i){//遍历
        //分别遍历两个字符串，取相同位置的字符
            x = s.charAt(i);
            y = t.charAt(i);
            //两个集合的键值对分别反向存储两个取得的字符
            //在不断遍历过程中，如果发现新的键值对与已存在的键值对的关系不同，就代表不能同构了
            if(s2t.containsKey(x)&&s2t.get(x)!=y||t2s.containsKey(y)&&t2s.get(y)!=x){return false;}
            //两个集合的键值对分别反向存储两个取得的字符
            s2t.put(x,y);
            t2s.put(y,x);
        }
        return true; //若两个集合键值对没有发生冲突,返回真
    }
}



